﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using personalplaner.business.stamm;
using personalplaner.common.mvvm;
using personalplaner.common.mvvm.commands;
using personalplaner.servicemodel.dataaccess;
using personalplaner.gui.common;
using personalplaner.business;

namespace personalplaner.gui.stamm.viewmodels
{
	public class AddAbteilungToSchemaViewModel : BaseViewModel
	{
		public AddAbteilungToSchemaViewModel(DependencyObject parent)
			: base(parent)
		{
		}

		#region Implementation

		public override void Loaded()
		{
			var mw = GetService<IMainWindowDisplayContainer>();
			mw.IsWaitVisible = false;
		}

		internal void SetAbteilungenZugeteilt(IList<Abteilung> value)
		{
			foreach (var abt in value)
			{
				foreach (var anz in AbteilungenNichtZugeteilt)
				{
					if (anz.AbteilungID == abt.AbteilungID)
					{
						AbteilungenNichtZugeteilt.Remove(anz);
						AbteilungenZugeteilt.Add(anz);
						break;
					}
				}
			}
		}

		#endregion

		#region Commands

		ICommand _okcommand;
		public ICommand OkCommand
		{
			get
			{
				if (_okcommand == null)
					_okcommand = new RelayCommand(OnOkCommand, parameter => AbteilungenZugeteilt.Count > 0);
				return _okcommand;
			}
		}

		private void OnOkCommand(object parameter)
		{
			var wnd = Parent as Window;
			if (wnd == null)
				throw new Exception();
			
			wnd.DialogResult = true;
			wnd.Close();
		}

		ICommand _addToListCommand;
		public ICommand AddToListCommand
		{
			get
			{
				if (_addToListCommand == null)
					_addToListCommand = new RelayCommand(OnAddToList, parameter => SelectedAbteilungNichtZugeteilt != null);
				return _addToListCommand;
			}
		}

		private void OnAddToList(object parameter)
		{
			if (SelectedAbteilungNichtZugeteilt == null)
				return;

			var abteilung = SelectedAbteilungNichtZugeteilt;

			AbteilungenZugeteilt.Add(abteilung);
			AbteilungenNichtZugeteilt.Remove(abteilung);

		}

		ICommand _removeFromListCommand;
		public ICommand RemoveFromListCommand
		{
			get
			{
				if (_removeFromListCommand == null)
					_removeFromListCommand = new RelayCommand(OnRemoveFromList, parameter => SelectedAbteilungZugeteilt != null);
				return _removeFromListCommand;
			}
		}

		private void OnRemoveFromList(object parameter)
		{
			if (SelectedAbteilungZugeteilt == null)
				return;

			var abteilung = SelectedAbteilungZugeteilt;
			AbteilungenZugeteilt.Remove(abteilung);
			AbteilungenNichtZugeteilt.Add(abteilung);
		}

		ICommand _moveUpCommand;
		public ICommand MoveUpCommand
		{
			get
			{
				if (_moveUpCommand == null)
					_moveUpCommand = new RelayCommand(OnMoveUp, CanMoveUp);
				return _moveUpCommand;
			}
		}

		private void OnMoveUp(object parameter)
		{
			var i = AbteilungenZugeteilt.IndexOf(SelectedAbteilungZugeteilt);
			var tmp = SelectedAbteilungZugeteilt;
			AbteilungenZugeteilt.Remove(tmp);
			AbteilungenZugeteilt.Insert(i - 1, tmp);

			SelectedAbteilungZugeteilt = tmp;
		}

		private bool CanMoveUp(object parameter)
		{
			return AbteilungenZugeteilt.Count > 0 &&
				SelectedAbteilungZugeteilt != null &&
				SelectedAbteilungZugeteilt != AbteilungenZugeteilt[0];
		}

		ICommand _moveDownCommand;
		public ICommand MoveDownCommand
		{
			get
			{
				if (_moveDownCommand == null)
					_moveDownCommand = new RelayCommand(OnMoveDown, CanMoveDown);
				return _moveDownCommand;
			}
		}

		private void OnMoveDown(object parameter)
		{
			var i = AbteilungenZugeteilt.IndexOf(SelectedAbteilungZugeteilt);
			var tmp = SelectedAbteilungZugeteilt;
			AbteilungenZugeteilt.Remove(tmp);
			AbteilungenZugeteilt.Insert(i + 1, tmp);

			SelectedAbteilungZugeteilt = tmp;
		}

		private bool CanMoveDown(object parameter)
		{
			return AbteilungenZugeteilt.Count > 0 &&
				SelectedAbteilungZugeteilt != null &&
				SelectedAbteilungZugeteilt != AbteilungenZugeteilt[AbteilungenZugeteilt.Count - 1];
		}

		#endregion

		#region Properties

		IList<Abteilung> _abteilungenZugeteilt;
		public IList<Abteilung> AbteilungenZugeteilt
		{
			get
			{
				if (_abteilungenZugeteilt == null)
					_abteilungenZugeteilt = new ObservableCollection<Abteilung>();
				return _abteilungenZugeteilt;
			}
			set
			{
				_abteilungenZugeteilt = value;
				RaisePropertyChanged("AbteilungenZugeteilt");
			}
		}

		Abteilung _selectedAbteilungZugeteilt;
		public Abteilung SelectedAbteilungZugeteilt
		{
			get
			{
				return _selectedAbteilungZugeteilt;
			}
			set
			{
				_selectedAbteilungZugeteilt = value;
				RaisePropertyChanged("SelectedAbteilungZugeteilt");
			}
		}

		IList<Abteilung> _abteilungenNichtZugeteilt;
		public IList<Abteilung> AbteilungenNichtZugeteilt
		{
			get
			{
				if (_abteilungenNichtZugeteilt == null)
				{
					var da = GetService<IAbteilungDataAccess>();
					var lst = da.GetAbteilungen();
					_abteilungenNichtZugeteilt = lst != null ? new ObservableCollection<Abteilung>(lst) : new ObservableCollection<Abteilung>();
				}
				return _abteilungenNichtZugeteilt;
			}
			set
			{
				_abteilungenNichtZugeteilt = value;
				RaisePropertyChanged("AbteilungenNichtZugeteilt");
			}
		}

		Abteilung _selectedAbteilungNichtZugeteilt;
		public Abteilung SelectedAbteilungNichtZugeteilt
		{
			get
			{
				return _selectedAbteilungNichtZugeteilt;
			}
			set
			{
				_selectedAbteilungNichtZugeteilt = value;
				RaisePropertyChanged("SelectedAbteilungNichtZugeteilt");
			}
		}

		#endregion
	}
}
